package com.za.plugin.transfer.form.insertupdate;

import com.alibaba.druid.sql.SQLUtils;
import com.alibaba.druid.sql.ast.SQLExpr;
import com.alibaba.druid.sql.ast.SQLStatement;
import com.alibaba.druid.sql.ast.statement.SQLInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.ast.statement.MySqlInsertStatement;
import com.alibaba.druid.sql.dialect.mysql.parser.MySqlStatementParser;
import org.apache.ibatis.mapping.ParameterMapping;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class Insert2StyleTransfer implements StyleTransfer {
    @Override
    public boolean isSupport(String sql) {
        return sql.trim().startsWith("insert") && !sql.contains("on duplicate key update");
    }

    @Override
    public String transfer(String sql, String tableName, List<String> autoIncrProperties, List<ParameterMapping> parameterMappingsCopy, List<ParameterMapping> parameterMappings, Set<String> pKs, Map<String, List<String>> pkAndUniqueKeys) {
        MySqlStatementParser parser = new MySqlStatementParser(sql.toLowerCase());
        SQLStatement sqlStatement = parser.parseStatement();
        Pattern compile = Pattern.compile("\\s*insert\\s+into\\s+(.*?)select\\s+");
        Matcher matcher = compile.matcher(sql.toLowerCase());
        if (matcher.find()) {
            return sql;
        }

        List<Integer> skipIdxList = new ArrayList<>();
        if (sqlStatement instanceof SQLInsertStatement) {
            List<SQLExpr> columns = ((SQLInsertStatement) sqlStatement).getColumns();
            int size = ((MySqlInsertStatement) sqlStatement).getValuesList().size();
            List<SQLExpr> values = ((MySqlInsertStatement) sqlStatement).getValuesList().get(0).getValues();
            StringBuilder sb = new StringBuilder();
//            String tableName = ((SQLInsertStatement) sqlStatement).getTableName().getSimpleName();
            int i = 0;
            sb.append("insert into ").append(tableName).append("(");
            for (SQLExpr column : columns) {
                System.out.println(SQLUtils.toMySqlString(column));
                if (autoIncrProperties.contains(SQLUtils.toMySqlString(column))) {
                    skipIdxList.add(i);
                } else {
                    sb.append(column).append(",");
                }
                i++;
            }
            sb.deleteCharAt(sb.length() - 1).append(") values ");
            for (int k = 0; k < size; k++) {
                sb.append("(");
                for (int j = 0; j < values.size(); j++) {
                    if (!skipIdxList.contains(j)) {
                        sb.append(SQLUtils.toMySqlString(values.get(j))).append(",");
                    }
                }
                sb.deleteCharAt(sb.length() - 1).append("),");
            }
            HashSet<Integer> idSet = new HashSet<>();
            for (int j = 0; j < size; j++) {
                for (Integer idx : skipIdxList) {
                    idSet.add(idx + j * values.size());
                }
            }
            for (int j = 0; j < parameterMappingsCopy.size(); j++) {
                if (!idSet.contains(j)) {
                    parameterMappings.add(parameterMappingsCopy.get(j));
                }
            }
            sb.deleteCharAt(sb.length() - 1);
            return sb.toString();
        }
        return sql;

    }
}
